/*
 *  Class name: XMLReaderWriter.java
 *  Version: 1.0
 *  Date: 3.6.2014
 */
package cz.muni.fi.pv168.addressbook.entities.xml;

import cz.muni.fi.pv168.addressbook.entities.Contact;
import cz.muni.fi.pv168.addressbook.entities.ContactType;
import cz.muni.fi.pv168.addressbook.entities.Person;
import cz.muni.fi.pv168.addressbook.utils.FileHandler;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.namespace.QName;
import javax.xml.transform.stream.StreamSource;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;

/**
 *
 * @author Michal Ďuriš
 * @param <E>
 */
public class XMLReaderWriter<E> {

    private static final String DIRECTORY = "storage";

    private final String fileName;
    private File file;

    private JAXBContext context;

    public XMLReaderWriter(String fileName) {
        this.fileName = fileName;
    }

    public void init() throws JAXBException, IOException {

        context = JAXBContext.newInstance(Wrapper.class, Person.class,
                Contact.class, ContactType.class);

        file = FileUtils.getFile(DIRECTORY, fileName);

        if (FileHandler.createFile(file)) {
            store(new ArrayList<>());
        }
    }

    public void store(List<E> entityList) throws JAXBException, IOException {

        try (OutputStream outputStream = new FileOutputStream(file)) {

            Marshaller marshaller = context.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

            JAXBElement<Wrapper> element = new JAXBElement<>(new QName(
                    FilenameUtils.removeExtension(fileName)), Wrapper.class,
                    new Wrapper(entityList));

            marshaller.marshal(element, outputStream);

        } catch (IOException ex) {
            Logger.getLogger(XMLReaderWriter.class.getName())
                    .log(Level.SEVERE, null, ex);

            throw new IOException();
        }
    }

    public List<E> load() throws JAXBException {

        Unmarshaller unmarshaller = context.createUnmarshaller();

        StreamSource source = new StreamSource(file);

        return unmarshaller.unmarshal(source, Wrapper.class).getValue()
                .getItems();
    }
}
